/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include "../节点.h"
#include "物理/物理.h"


struct S_物体;



class API_EXPORT C_FLIP解算器节点 : public C_节点基类 {
	
	S_设备环境	m_GPU环境;
	//S_物体*		m_数据可视物体;

public:
	C_FLIP解算器节点(E_物理引擎 解算器类型, S_设备环境& ctx);
	~C_FLIP解算器节点();

	E_物理引擎	m_解算器类型;

	bool	f_update();


	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_加载FLIP解算器节点(S_设备环境& ctx, FILE* f);
void		f_node_保存FLIP解算器节点(C_节点基类* n, FILE* f);




class API_EXPORT C_PBF解算器节点 : public C_节点基类 {
	E_物理引擎	m_解算器类型;
	//S_设备环境	m_GPU环境;
	uint64	m_记录物理体状态;
public:
	C_PBF解算器节点(S_设备环境& ctx);
	~C_PBF解算器节点();

	S_Props	m_物理引擎类型;
	S_Props	m_GPU;
	S_Props	m_飞溅粒子数量;
	
	S_Props	m_显示粒子;
	S_Props	m_显示体素;
	//S_Props	m_缓存路径;
	//S_Props	m_缓存偏移;

	bool	f_update();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_加载PBF解算器节点(S_设备环境& ctx, FILE* f);
void		f_node_保存PBF解算器节点(C_节点基类* n, FILE* f);







class API_EXPORT C_物理引擎节点 : public C_节点基类 {
	//E_物理引擎	m_解算器类型;
	uint64			m_记录物理体状态;
	S_动画曲线组*	m_动画曲线列表;

	std::vector<C_节点基类*> m_InNodes;
	std::vector<C_节点基类*> m_OutNudes;

	S_物体* m_域可视物体;
public:
	C_物理引擎节点(S_设备环境& ctx, C_节点树* link_tree);
	~C_物理引擎节点();

	S_Props	m_物理引擎类型;
	S_Props	m_模型读写路径;

	
	S_Props	m_GPU;
	S_Props	m_域大小;
	S_Props	m_单元大小;
	S_Props	m_飞溅粒子数量;
	S_Props	m_开启飞溅粒子;
	
	S_Props	m_清除所有缓存;
	

	bool	f_update();
	void	f_异步解算();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);

	S_物体* f_虚拟体();
	void	f_删除();
	void	f_回收();
};

C_节点基类* f_node_创建物理引擎节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载物理引擎节点(S_设备环境& ctx, FILE* f);
void		f_node_保存物理引擎节点(C_节点基类* n, FILE* f);






class API_EXPORT C_PBF粒子容器节点 : public C_节点基类 {
public:
	C_PBF粒子容器节点(S_设备环境& ctx);
	~C_PBF粒子容器节点();

	bool	f_update();

	//void	f_读取(FILE* f);
	//void	f_写入(FILE* f);
};

C_节点基类* f_node_加载PBF粒子容器节点(S_设备环境& ctx, FILE* f);
void		f_node_保存PBF粒子容器节点(C_节点基类* n, FILE* f);





class API_EXPORT C_应用力节点 : public C_节点基类 {
public:
	C_应用力节点(S_设备环境& ctx);
	~C_应用力节点();

	S_Props	m_视口互交;
	S_Props	m_力方式;

	bool	f_update();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建应用力节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载应用力节点(S_设备环境& ctx, FILE* f);
void		f_node_保存应用力节点(C_节点基类* n, FILE* f);



class API_EXPORT C_PBF更新邻接信息节点 : public C_节点基类 {
public:
	C_PBF更新邻接信息节点(S_设备环境& ctx);
	~C_PBF更新邻接信息节点();

	bool	f_update();
};

C_节点基类* f_node_加载PBF更新邻接信息节点(S_设备环境& ctx, FILE* f);
void		f_node_保存PBF更新邻接信息节点(C_节点基类* n, FILE* f);




class API_EXPORT C_PBF参数节点 : public C_节点基类 {
	S_PBF_Params m_流体粒子模拟参数;

public:
	C_PBF参数节点(S_设备环境& ctx);
	~C_PBF参数节点();

	S_Props	m_迭代次数;
	S_Props	m_粒子半径;
	S_Props	m_固体重置距离;
	S_Props	m_流体重置距离;

	S_Props	m_最大加速度;
	S_Props	m_最大速度;

	S_Props	m_风向;
	S_Props	m_布料拖拽;
	S_Props	m_空气阻力;

	S_Props	m_动态摩擦;
	S_Props	m_静态摩擦;
	S_Props	m_粒子摩擦;
	S_Props	m_碰撞重置;
	S_Props	m_附着力;
	S_Props	m_休眠;
	S_Props	m_传播收敛;
	S_Props	m_消散;
	S_Props	m_阻力;

	S_Props	m_凝聚性;
	S_Props	m_表面张力;
	S_Props	m_粘度;
	S_Props	m_涡流;
	S_Props	m_流体球拉伸大小;
	S_Props	m_流体球拉伸最小;
	S_Props	m_流体球拉伸最大;
	S_Props	m_平滑强度;
	S_Props	m_固体压力;
	S_Props	m_边界阻力;
	S_Props	m_浮力;


	S_Props	m_飞溅产生;
	S_Props	m_飞溅浮力;
	S_Props	m_飞溅阻力;
	S_Props	m_飞溅发射;
	S_Props	m_飞溅寿命;


	S_Props	m_碰撞距离;
	S_Props	m_碰撞距离边缘;
	S_Props	m_碰撞形状边缘;


	S_Props	m_松弛;
	S_Props	m_松弛模式;



	bool	f_update();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建PBF参数节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载PBF参数节点(S_设备环境& ctx, FILE* f);
void		f_node_保存PBF参数节点(C_节点基类* n, FILE* f);





class API_EXPORT C_解算器更新节点 : public C_节点基类 {
	S_物体* m_数据可视物体;
	S_物体* m_飞溅可视物体;
	S_物体* m_肌腱可视物体;
	uint32	m_上一次可视数据分辨率;
	float32	m_上一次可视数据间隔;

	std::vector<vec4> m_体素顶点;
	std::vector<vec4> m_飞溅顶点;

	uint8			m_是否完成计算;
	int32			m_缓存保存帧;
public:
	C_解算器更新节点(S_设备环境& ctx);
	~C_解算器更新节点();

	bool m_显示域体素;
	//S_Props	m_粒子是否可视;
	S_Props	m_是否多线程;
	S_Props	m_时间区间;
	S_Props	m_是否缓存;
	
	//S_Props	m_缓存名称;
	S_Props	m_缓存方式;
	S_Props	m_缓存路径;
	S_Props	m_文件名;
	S_Props	m_缓存压缩;
	
	S_Props	m_清除当前帧后缓存;

	S_Props	m_保留缓存设备;
	S_Props	m_保留缓存数量;

	S_Props	m_重置时间;
	S_Props	m_视口互交;
	S_Props	m_时间步进;
	S_Props	m_子帧;
	S_Props	m_变换物体;

	S_Props m_可视项;

	bool	f_update();
	void	f_异步解算();
	
	void	f_读取(FILE* f);
	void	f_写入(FILE* f);

	S_物体* f_虚拟体();
	void	f_删除();
	void	f_回收();

	//S_插座增减方式	f_动态添加插座(E_插座方向 方向);
	std::string	f_get缓存路径(S_Physics* Physics, const std::string& type, int32 帧, bool 序列 = true);
	int32		f_get时间帧();

	void	f_粒子可视更新(S_Physics* physics);
	//bool	f_uodate_FleX调试物体(std::vector<vec4>& 流体粒子, std::vector<vec4>& 飞溅粒子);
};

C_节点基类* f_node_创建解算器更新节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载解算器更新节点(S_设备环境& ctx, FILE* f);
void		f_node_保存解算器更新节点(C_节点基类* n, FILE* f);









class API_EXPORT C_解算器添加物体节点 : public C_节点基类 {

public:
	C_解算器添加物体节点(S_设备环境& ctx);
	~C_解算器添加物体节点();

	bool	f_update();
	void	f_异步解算();
	//void	f_读取(FILE* f);
	//void	f_写入(FILE* f);
};

C_节点基类* f_node_加载解算器添加物体节点(S_设备环境& ctx, FILE* f);








class API_EXPORT C_更新肌腱节点 : public C_节点基类 {
	
public:
	C_更新肌腱节点(S_设备环境& ctx);
	~C_更新肌腱节点();

	bool	f_update();
	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
	
};

C_节点基类* f_node_加载更新肌腱节点(S_设备环境& ctx, FILE* f);
void		f_node_保存更新肌腱节点(C_节点基类* n, FILE* f);


/*class C_粒子节点 : public C_节点基类 {
	
public:
	C_粒子节点(S_设备环境& ctx);
	~C_粒子节点();

	bool m_是否多线程;
	bool m_显示域体素;


	bool	f_update();
	void	f_异步解算();
};

C_节点基类* f_node_加载粒子节点(S_设备环境& ctx, FILE* f);
void		f_node_保存粒子节点(C_节点基类* n, FILE* f);*/












